package dos

import (
	"bytes"
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"strings"
	"time"
)

// AttackEvaluationResult 攻击评估结果
type AttackEvaluationResult struct {
	TargetInfo             *TargetInfo `json:"target_info"`
	AttackType             string      `json:"attack_type"`
	StartTime              time.Time   `json:"start_time"`
	EndTime                time.Time   `json:"end_time"`
	Duration               float64     `json:"duration"`
	PreAttackResponseTime  float64     `json:"pre_attack_response_time"`
	PostAttackResponseTime float64     `json:"post_attack_response_time"`
	ResponseTimeDiff       float64     `json:"response_time_diff"`
	ResponseTimeImpact     float64     `json:"response_time_impact"`
	PreAttackSuccessRate   float64     `json:"pre_attack_success_rate"`
	PostAttackSuccessRate  float64     `json:"post_attack_success_rate"`
	SuccessRateDiff        float64     `json:"success_rate_diff"`
	AvailabilityImpact     float64     `json:"availability_impact"`
	PerformanceImpact      float64     `json:"performance_impact"`
	OverallImpact          float64     `json:"overall_impact"`
	EffectivenessLevel     string      `json:"effectiveness_level"`
	StatusCodeStats        map[int]int `json:"status_code_stats"`
	ConnectionErrors       int         `json:"connection_errors"`
	TotalRequests          int         `json:"total_requests"`
	SuccessfulRequests     int         `json:"successful_requests"`
}

// NewAttackEvaluationSystem 创建新的攻击评估系统
func NewAttackEvaluationSystem() *AttackEvaluationSystem {
	return &AttackEvaluationSystem{
		statusCodeHistory:   make(map[int]int),
		responseTimeHistory: make([]float64, 0),
		reportGenerator: &ReportGenerator{
			outputFormats: []string{"txt", "json", "html"},
			detailLevel:   "detailed",
		},
	}
}

// CollectBaselineMetrics 收集基准指标
func (s *AttackEvaluationSystem) CollectBaselineMetrics(target *TargetInfo) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	// 测量目标响应时间
	responseTime, err := measureResponseTime(target)
	if err != nil {
		return err
	}
	s.preAttackResponseTime = responseTime

	// 测量请求成功率
	successRate, statusCodes, err := measureSuccessRate(target, 10)
	if err != nil {
		return err
	}
	s.preAttackSuccessRate = successRate

	// 记录状态码统计
	for code, count := range statusCodes {
		s.statusCodeHistory[code] = count
	}

	return nil
}

// CollectPostAttackMetrics 收集攻击后指标
func (s *AttackEvaluationSystem) CollectPostAttackMetrics(target *TargetInfo) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	// 测量目标响应时间
	responseTime, err := measureResponseTime(target)
	if err != nil {
		return err
	}
	s.postAttackResponseTime = responseTime

	// 测量请求成功率
	successRate, statusCodes, err := measureSuccessRate(target, 10)
	if err != nil {
		return err
	}
	s.postAttackSuccessRate = successRate

	// 更新状态码统计
	for code, count := range statusCodes {
		s.statusCodeHistory[code] += count
	}

	// 计算性能影响
	if s.preAttackResponseTime > 0 {
		responseTimeDiff := s.postAttackResponseTime - s.preAttackResponseTime
		s.performanceImpact = min(1.0, responseTimeDiff/s.preAttackResponseTime)
	}

	// 计算可用性影响
	successRateDiff := s.preAttackSuccessRate - s.postAttackSuccessRate
	s.availabilityImpact = min(1.0, successRateDiff/100.0)

	return nil
}

// GenerateReport 生成攻击评估报告
func (s *AttackEvaluationSystem) GenerateReport(target *TargetInfo, attackType string) *AttackEvaluationResult {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	// 计算持续时间
	duration := s.endTime.Sub(s.startTime).Seconds()

	// 计算响应时间差异
	responseTimeDiff := s.postAttackResponseTime - s.preAttackResponseTime

	// 计算成功率差异
	successRateDiff := s.preAttackSuccessRate - s.postAttackSuccessRate

	// 计算综合影响
	overallImpact := (s.performanceImpact + s.availabilityImpact) / 2

	// 确定效果级别
	var effectivenessLevel string
	switch {
	case overallImpact >= 0.8:
		effectivenessLevel = "极高"
	case overallImpact >= 0.6:
		effectivenessLevel = "高"
	case overallImpact >= 0.3:
		effectivenessLevel = "中"
	case overallImpact >= 0.1:
		effectivenessLevel = "低"
	default:
		effectivenessLevel = "极低"
	}

	// 创建评估结果
	result := &AttackEvaluationResult{
		TargetInfo:             target,
		AttackType:             attackType,
		StartTime:              s.startTime,
		EndTime:                s.endTime,
		Duration:               duration,
		PreAttackResponseTime:  s.preAttackResponseTime,
		PostAttackResponseTime: s.postAttackResponseTime,
		ResponseTimeDiff:       responseTimeDiff,
		ResponseTimeImpact:     s.performanceImpact,
		PreAttackSuccessRate:   s.preAttackSuccessRate,
		PostAttackSuccessRate:  s.postAttackSuccessRate,
		SuccessRateDiff:        successRateDiff,
		AvailabilityImpact:     s.availabilityImpact,
		PerformanceImpact:      s.performanceImpact,
		OverallImpact:          overallImpact,
		EffectivenessLevel:     effectivenessLevel,
		StatusCodeStats:        s.statusCodeHistory,
		TotalRequests:          s.evaluationSamples,
	}

	// 计算成功请求数
	successfulRequests := 0
	for code, count := range s.statusCodeHistory {
		if code >= 200 && code < 400 {
			successfulRequests += count
		}
	}
	result.SuccessfulRequests = successfulRequests

	// 计算连接错误数
	connectionErrors := 0
	if errCount, ok := s.statusCodeHistory[-1]; ok {
		connectionErrors = errCount
	}
	result.ConnectionErrors = connectionErrors

	// 设置报告生成器的评估系统
	s.reportGenerator.evaluationSystem = s

	return result
}

// ExportReport 导出攻击评估报告
func (s *AttackEvaluationSystem) ExportReport(result *AttackEvaluationResult, outputDir, format string) (string, error) {
	// 确保输出目录存在
	if err := os.MkdirAll(outputDir, 0755); err != nil {
		return "", fmt.Errorf("创建输出目录失败: %v", err)
	}

	// 生成报告文件名
	timestamp := time.Now().Format("20060102_150405")
	fileBase := fmt.Sprintf("dos_attack_report_%s_%s", result.AttackType, timestamp)

	var filePaths []string

	// 如果是"all"格式，导出所有格式
	if format == "all" {
		// 导出TXT格式
		txtPath := filepath.Join(outputDir, fileBase+".txt")
		if err := s.exportTextReport(result, txtPath); err != nil {
			return "", err
		}
		filePaths = append(filePaths, txtPath)

		// 导出JSON格式
		jsonPath := filepath.Join(outputDir, fileBase+".json")
		if err := s.exportJSONReport(result, jsonPath); err != nil {
			return "", err
		}
		filePaths = append(filePaths, jsonPath)

		// 导出HTML格式
		htmlPath := filepath.Join(outputDir, fileBase+".html")
		if err := s.exportHTMLReport(result, htmlPath); err != nil {
			return "", err
		}
		filePaths = append(filePaths, htmlPath)

		return strings.Join(filePaths, ","), nil
	}

	// 根据格式导出单一格式报告
	switch format {
	case "txt":
		txtPath := filepath.Join(outputDir, fileBase+".txt")
		if err := s.exportTextReport(result, txtPath); err != nil {
			return "", err
		}
		return txtPath, nil
	case "json":
		jsonPath := filepath.Join(outputDir, fileBase+".json")
		if err := s.exportJSONReport(result, jsonPath); err != nil {
			return "", err
		}
		return jsonPath, nil
	case "html":
		htmlPath := filepath.Join(outputDir, fileBase+".html")
		if err := s.exportHTMLReport(result, htmlPath); err != nil {
			return "", err
		}
		return htmlPath, nil
	default:
		return "", fmt.Errorf("不支持的报告格式: %s", format)
	}
}

// exportTextReport 导出文本格式报告
func (s *AttackEvaluationSystem) exportTextReport(result *AttackEvaluationResult, filePath string) error {
	var buffer bytes.Buffer

	buffer.WriteString("============================================\n")
	buffer.WriteString("          DOS攻击效果评估报告              \n")
	buffer.WriteString("============================================\n\n")

	// 添加目标信息
	buffer.WriteString("【目标信息】\n")
	buffer.WriteString(fmt.Sprintf("主机: %s\n", result.TargetInfo.host))
	if result.TargetInfo.port != "" {
		buffer.WriteString(fmt.Sprintf("端口: %s\n", result.TargetInfo.port))
	}
	if result.TargetInfo.url != "" {
		buffer.WriteString(fmt.Sprintf("URL: %s\n", result.TargetInfo.url))
	}
	if result.TargetInfo.webServer != "" {
		buffer.WriteString(fmt.Sprintf("Web服务器: %s\n", result.TargetInfo.webServer))
	}
	buffer.WriteString("\n")

	// 添加攻击信息
	buffer.WriteString("【攻击信息】\n")
	buffer.WriteString(fmt.Sprintf("攻击类型: %s\n", result.AttackType))
	buffer.WriteString(fmt.Sprintf("开始时间: %s\n", result.StartTime.Format("2006-01-02 15:04:05")))
	buffer.WriteString(fmt.Sprintf("结束时间: %s\n", result.EndTime.Format("2006-01-02 15:04:05")))
	buffer.WriteString(fmt.Sprintf("持续时间: %.2f秒\n\n", result.Duration))

	// 添加性能影响信息
	buffer.WriteString("【性能影响】\n")
	buffer.WriteString(fmt.Sprintf("攻击前平均响应时间: %.3f秒\n", result.PreAttackResponseTime))
	buffer.WriteString(fmt.Sprintf("攻击后平均响应时间: %.3f秒\n", result.PostAttackResponseTime))

	if result.ResponseTimeDiff > 0 {
		buffer.WriteString(fmt.Sprintf("响应时间增加: %.3f秒 (%.1f%%)\n", result.ResponseTimeDiff, (result.ResponseTimeDiff/result.PreAttackResponseTime)*100))
	} else {
		buffer.WriteString(fmt.Sprintf("响应时间减少: %.3f秒 (%.1f%%)\n", -result.ResponseTimeDiff, -(result.ResponseTimeDiff/result.PreAttackResponseTime)*100))
	}
	buffer.WriteString(fmt.Sprintf("性能影响评分: %.2f/1.00\n\n", result.PerformanceImpact))

	// 添加可用性影响信息
	buffer.WriteString("【可用性影响】\n")
	buffer.WriteString(fmt.Sprintf("攻击前请求成功率: %.1f%%\n", result.PreAttackSuccessRate))
	buffer.WriteString(fmt.Sprintf("攻击后请求成功率: %.1f%%\n", result.PostAttackSuccessRate))

	if result.SuccessRateDiff > 0 {
		buffer.WriteString(fmt.Sprintf("请求成功率下降: %.1f%%\n", result.SuccessRateDiff))
	} else {
		buffer.WriteString(fmt.Sprintf("请求成功率上升: %.1f%%\n", -result.SuccessRateDiff))
	}
	buffer.WriteString(fmt.Sprintf("可用性影响评分: %.2f/1.00\n\n", result.AvailabilityImpact))

	// 添加综合评估信息
	buffer.WriteString("【综合评估】\n")
	buffer.WriteString(fmt.Sprintf("综合影响评分: %.2f/1.00\n", result.OverallImpact))
	buffer.WriteString(fmt.Sprintf("攻击效果级别: %s\n\n", result.EffectivenessLevel))

	// 添加状态码统计
	buffer.WriteString("【状态码统计】\n")
	for code, count := range result.StatusCodeStats {
		if code == -1 {
			buffer.WriteString(fmt.Sprintf("连接错误: %d 个\n", count))
		} else {
			buffer.WriteString(fmt.Sprintf("HTTP %d: %d 个\n", code, count))
		}
	}
	buffer.WriteString(fmt.Sprintf("总请求数: %d\n", result.TotalRequests))
	buffer.WriteString(fmt.Sprintf("成功请求数: %d\n", result.SuccessfulRequests))
	buffer.WriteString(fmt.Sprintf("连接错误数: %d\n\n", result.ConnectionErrors))

	buffer.WriteString("============================================\n")

	// 写入文件
	return ioutil.WriteFile(filePath, buffer.Bytes(), 0644)
}

// exportJSONReport 导出JSON格式报告
func (s *AttackEvaluationSystem) exportJSONReport(result *AttackEvaluationResult, filePath string) error {
	// 将结果转换为JSON
	jsonData, err := json.MarshalIndent(result, "", "  ")
	if err != nil {
		return fmt.Errorf("JSON编码失败: %v", err)
	}

	// 写入文件
	return ioutil.WriteFile(filePath, jsonData, 0644)
}

// exportHTMLReport 导出HTML格式报告
func (s *AttackEvaluationSystem) exportHTMLReport(result *AttackEvaluationResult, filePath string) error {
	// HTML模板
	const htmlTemplate = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DOS攻击评估报告</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            color: #333;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: #fff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        h1 {
            color: #c00;
            text-align: center;
            border-bottom: 2px solid #eee;
            padding-bottom: 10px;
        }
        h2 {
            color: #333;
            border-left: 4px solid #c00;
            padding-left: 10px;
        }
        .section {
            margin-bottom: 20px;
        }
        .impact-high {
            color: #c00;
            font-weight: bold;
        }
        .impact-medium {
            color: #f90;
            font-weight: bold;
        }
        .impact-low {
            color: #090;
            font-weight: bold;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin: 10px 0;
        }
        table, th, td {
            border: 1px solid #ddd;
        }
        th, td {
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        .footer {
            text-align: center;
            margin-top: 20px;
            font-size: 0.8em;
            color: #777;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>DOS攻击评估报告</h1>
        
        <div class="section">
            <h2>目标信息</h2>
            <table>
                <tr>
                    <th>主机</th>
                    <td>{{.TargetInfo.host}}</td>
                </tr>
                {{if .TargetInfo.port}}
                <tr>
                    <th>端口</th>
                    <td>{{.TargetInfo.port}}</td>
                </tr>
                {{end}}
                {{if .TargetInfo.url}}
                <tr>
                    <th>URL</th>
                    <td>{{.TargetInfo.url}}</td>
                </tr>
                {{end}}
                {{if .TargetInfo.webServer}}
                <tr>
                    <th>Web服务器</th>
                    <td>{{.TargetInfo.webServer}}</td>
                </tr>
                {{end}}
            </table>
        </div>
        
        <div class="section">
            <h2>攻击信息</h2>
            <table>
                <tr>
                    <th>攻击类型</th>
                    <td>{{.AttackType}}</td>
                </tr>
                <tr>
                    <th>开始时间</th>
                    <td>{{formatTime .StartTime}}</td>
                </tr>
                <tr>
                    <th>结束时间</th>
                    <td>{{formatTime .EndTime}}</td>
                </tr>
                <tr>
                    <th>持续时间</th>
                    <td>{{printf "%.2f" .Duration}}秒</td>
                </tr>
            </table>
        </div>
        
        <div class="section">
            <h2>性能影响</h2>
            <table>
                <tr>
                    <th>攻击前平均响应时间</th>
                    <td>{{printf "%.3f" .PreAttackResponseTime}}秒</td>
                </tr>
                <tr>
                    <th>攻击后平均响应时间</th>
                    <td>{{printf "%.3f" .PostAttackResponseTime}}秒</td>
                </tr>
                <tr>
                    <th>响应时间变化</th>
                    <td>
                        {{if gt .ResponseTimeDiff 0}}
                            增加 {{printf "%.3f" .ResponseTimeDiff}}秒 
                            ({{printf "%.1f" (mul (div .ResponseTimeDiff .PreAttackResponseTime) 100)}}%)
                        {{else}}
                            减少 {{printf "%.3f" (neg .ResponseTimeDiff)}}秒
                            ({{printf "%.1f" (mul (div (neg .ResponseTimeDiff) .PreAttackResponseTime) 100)}}%)
                        {{end}}
                    </td>
                </tr>
                <tr>
                    <th>性能影响评分</th>
                    <td class="{{impactClass .PerformanceImpact}}">
                        {{printf "%.2f" .PerformanceImpact}}/1.00
                    </td>
                </tr>
            </table>
        </div>
        
        <div class="section">
            <h2>可用性影响</h2>
            <table>
                <tr>
                    <th>攻击前请求成功率</th>
                    <td>{{printf "%.1f" .PreAttackSuccessRate}}%</td>
                </tr>
                <tr>
                    <th>攻击后请求成功率</th>
                    <td>{{printf "%.1f" .PostAttackSuccessRate}}%</td>
                </tr>
                <tr>
                    <th>请求成功率变化</th>
                    <td>
                        {{if gt .SuccessRateDiff 0}}
                            下降 {{printf "%.1f" .SuccessRateDiff}}%
                        {{else}}
                            上升 {{printf "%.1f" (neg .SuccessRateDiff)}}%
                        {{end}}
                    </td>
                </tr>
                <tr>
                    <th>可用性影响评分</th>
                    <td class="{{impactClass .AvailabilityImpact}}">
                        {{printf "%.2f" .AvailabilityImpact}}/1.00
                    </td>
                </tr>
            </table>
        </div>
        
        <div class="section">
            <h2>综合评估</h2>
            <table>
                <tr>
                    <th>综合影响评分</th>
                    <td class="{{impactClass .OverallImpact}}">
                        {{printf "%.2f" .OverallImpact}}/1.00
                    </td>
                </tr>
                <tr>
                    <th>攻击效果级别</th>
                    <td class="{{impactClass .OverallImpact}}">
                        {{.EffectivenessLevel}}
                    </td>
                </tr>
            </table>
        </div>
        
        <div class="section">
            <h2>状态码统计</h2>
            <table>
                <tr>
                    <th>状态码</th>
                    <th>数量</th>
                </tr>
                {{range $code, $count := .StatusCodeStats}}
                <tr>
                    <td>
                        {{if eq $code -1}}
                            连接错误
                        {{else}}
                            HTTP {{$code}}
                        {{end}}
                    </td>
                    <td>{{$count}}</td>
                </tr>
                {{end}}
                <tr>
                    <th>总请求数</th>
                    <td>{{.TotalRequests}}</td>
                </tr>
                <tr>
                    <th>成功请求数</th>
                    <td>{{.SuccessfulRequests}}</td>
                </tr>
                <tr>
                    <th>连接错误数</th>
                    <td>{{.ConnectionErrors}}</td>
                </tr>
            </table>
        </div>
        
        <div class="footer">
            <p>报告生成时间: {{now}}</p>
        </div>
    </div>
</body>
</html>
`

	// 创建模板函数
	funcMap := template.FuncMap{
		"formatTime": func(t time.Time) string {
			return t.Format("2006-01-02 15:04:05")
		},
		"now": func() string {
			return time.Now().Format("2006-01-02 15:04:05")
		},
		"mul": func(a, b float64) float64 {
			return a * b
		},
		"div": func(a, b float64) float64 {
			if b == 0 {
				return 0
			}
			return a / b
		},
		"neg": func(a float64) float64 {
			return -a
		},
		"impactClass": func(impact float64) string {
			switch {
			case impact >= 0.6:
				return "impact-high"
			case impact >= 0.3:
				return "impact-medium"
			default:
				return "impact-low"
			}
		},
	}

	// 解析模板
	tmpl, err := template.New("report").Funcs(funcMap).Parse(htmlTemplate)
	if err != nil {
		return fmt.Errorf("模板解析失败: %v", err)
	}

	// 创建输出文件
	file, err := os.Create(filePath)
	if err != nil {
		return fmt.Errorf("创建文件失败: %v", err)
	}
	defer file.Close()

	// 执行模板
	if err := tmpl.Execute(file, result); err != nil {
		return fmt.Errorf("模板执行失败: %v", err)
	}

	return nil
}

// 测量目标响应时间
func measureResponseTime(target *TargetInfo) (float64, error) {
	// 实际实现中应该发送HTTP请求并测量响应时间
	// 这里简化为随机生成一个响应时间
	return 0.5 + rand.Float64()*0.5, nil
}

// 测量请求成功率
func measureSuccessRate(target *TargetInfo, samples int) (float64, map[int]int, error) {
	// 实际实现中应该发送多个HTTP请求并统计成功率
	// 这里简化为随机生成一个成功率和状态码统计
	statusCodes := make(map[int]int)

	// 模拟一些状态码
	statusCodes[200] = samples * 8 / 10 // 80% 成功
	statusCodes[404] = samples * 1 / 10 // 10% 404
	statusCodes[500] = samples * 1 / 10 // 10% 500

	// 计算成功率
	successCount := 0
	for code, count := range statusCodes {
		if code >= 200 && code < 400 {
			successCount += count
		}
	}

	successRate := float64(successCount) / float64(samples) * 100

	return successRate, statusCodes, nil
}
